using System;
using System.Collections.Generic;

namespace Atomic.Libraries.Plotting.Functions
{
	[Serializable]
	public class StepFunction : PlotFunction //, IRangedFunction
	{
		private int n;

		public StepFunction(IEnumerable<StepFunctionStep> steps, double y1, double y2)
		{
			n = 0;
			StepFunctionStep s0 = null;
			foreach (StepFunctionStep s in steps)
			{
				if (s0 != null)
				{
					if (s.X1 != s.X2)
					{
						throw new ArgumentException();
					}
				}
				s0 = s;
				n++;
			}

			if (n == 0 && y1 != y2)
			{
				throw new ArgumentException();
			}

			Y1 = y1;
			Y2 = y2;
			Steps = new ReadOnlyList<StepFunctionStep>(steps);
		}

		public override double Value(double x)
		{
			double y0 = Y1;

			if (x < Steps[0].X1 || n == 0)
			{
				return y0;
			}

			for (int i = 0; i < n; i++)
			{
				double y = Steps[i].Y;

				if (x == Steps[i].X1)
				{
					// Assume average between steps.
					return 0.5 * (y0 + y);
				}

				if (x < Steps[i].X2)
				{
					return y;
				}

				y0 = y;
			}

			if (x == Steps[n - 1].X2)
			{
				return 0.5 * (y0 + Y2);
			}

			return Y2;
		}

		public double Y1
		{
			get;
			private set;
		}

		public double Y2
		{
			get;
			private set;
		}

		public ReadOnlyList<StepFunctionStep> Steps
		{
			get;
			private set;
		}
	}
}
